package com.whf.android.jar.util;

import android.os.AsyncTask;
import android.text.TextUtils;

import androidx.annotation.NonNull;

import com.blankj.utilcode.util.TimeUtils;
import com.whf.android.jar.util.date.NetTimeAsyncTask;
import com.whf.android.jar.util.number.DoubleUtils;

import java.util.Calendar;
import java.util.Date;

/**
 * 数字、日期的格式化
 * <p>Calendar只能在类里使用，不能传值。
 *
 * @author hf
 * @version 1.0
 */
public final class FormatUtil {

    public final static String PATTERN = "yyyy-MM-dd HH:mm:ss";

    @NonNull
    public static Calendar nom() {
        return Calendar.getInstance();
    }

    /**
     * @param execute:获得网络时间
     */
    public static void getNetTime(NetTimeAsyncTask.IPostExecute execute) {
        try {
            NetTimeAsyncTask asyncTask = new NetTimeAsyncTask(execute);
            asyncTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, "https://www.baidu.com");
        } catch (Exception e) {
            e.printStackTrace();
            if (execute != null) {
                execute.onClick(TimeUtils.getNowString());
            }
        }
    }

    /**
     * 是否是凌晨（0-6点）
     */
    public static void beforeDawn(final NetTimeAsyncTask.IPostBooleanExecute boolExecute) {
        getNetTime(new NetTimeAsyncTask.IPostExecute() {
            @Override
            public void onClick(String result) {
                Calendar calendar = FormatUtil.string2Calendar(result);
                if (boolExecute != null) {
                    boolExecute.onClick(isBeforeDawn(calendar));
                }
            }
        });
    }

    //***************************** 设置日期的string的格式化 *************************

    /**
     * @param time:日期的String转string(默认是全时间)
     * @param pattern:转后的格式
     */
    @NonNull
    public static String string2String(String time, String pattern) {
        Date date = string2Date(time, PATTERN);
        return date2String(date, pattern);
    }

    /**
     * @param time:日期的String转date
     * @param pattern:需要转的time的格式
     * @param pattern2:转后的格式
     */
    @NonNull
    public static String string2String(String time, String pattern, String pattern2) {
        Date date = string2Date(time, pattern);
        return date2String(date, pattern2);
    }

    /***************************** 设置日期的string与date转换  *********************************/

    public static Date string2Date(String time) {
        return string2Date(time, PATTERN);
    }

    /**
     * @param time:日期的String转date
     * @param pattern:格式
     */
    public static Date string2Date(String time, String pattern) {
        return TimeUtils.string2Date(time, TimeUtils.getSafeDateFormat(pattern));
    }

    /**
     * @param time:日期的String转Calendar
     */
    @NonNull
    public static Calendar string2Calendar(String time) {
        return date2Calendar(TimeUtils.string2Date(time));
    }

    /**
     * @param time:日期的date转Calendar
     */
    @NonNull
    public static Calendar date2Calendar(Date time) {
        Calendar calendar = nom();
        calendar.setTime(time);
        return calendar;
    }

    /**
     * @param date:日期的date转String
     */
    @NonNull
    public static String date2String(Date date) {
        return date2String(date, PATTERN);
    }

    /**
     * @param date:日期的date转String
     * @param pattern:格式
     */
    @NonNull
    public static String date2String(Date date, String pattern) {
        return TimeUtils.date2String(date, TimeUtils.getSafeDateFormat(pattern));
    }

    //***************************** 设置日期的string与date转换  *********************************/

    /**
     * （2023-7-12）这里的7月前面没有0；
     *
     * @param date:日期的date转String
     */
    @NonNull
    public static String dateToString(Date date) {
        java.util.Calendar calendar = nom();
        calendar.setTime(date);

        int year = calendar.get(java.util.Calendar.YEAR);
        int month = calendar.get(java.util.Calendar.MONTH) + 1;
        int day = calendar.get(java.util.Calendar.DATE);

        return year + "-" + month + "-" + day;
    }

    /**
     * @param seconds:时间转换将秒转换为分钟:秒
     */
    @NonNull
    public static String string2Seconds(long seconds) {
        long m = (seconds / 60);
        long s = seconds - m * 60;
        if (m == 0) {
            return s + "";
        }
        if (s < 10) {
            return m + ":0" + s;
        }
        return m + ":" + s;
    }

    /**
     * @param seconds:时间转换 将秒转换为（分:秒）
     */
    @NonNull
    public static String string2SecondsEn(long seconds) {
        long m = (seconds / 60);
        long s = seconds - m * 60;
        if (m == 0) {
            return s + "秒";
        }
        if (s < 10) {
            return m + "分0" + s + "秒";
        }
        return m + "分" + s + "秒";
    }

    /**
     * @param minute:时间转换 将分钟转换为（时:分）
     */
    @NonNull
    public static String string2MinuteEn(long minute) {
        return string2MinuteEn(minute, false);
    }

    /**
     * @param minute:时间转换 将分钟转换为（时:分）
     */
    @NonNull
    public static String string2MinuteEn(long minute, boolean unit) {
        long h = (minute / 60);
        long m = minute - h * 60;
        if (h == 0) {
            return m + "分";
        }
        if (m < 10 && unit) {
            return h + "时0" + m + "分";
        }
        return h + "时" + m + "分";
    }

    /**
     * @param minute:时间转换 将分钟转换为（时:分）
     */
    @NonNull
    public static String string2MinuteEn2(long minute) {
        return string2MinuteEn2(minute, false);
    }

    /**
     * @param minute:时间转换 将分钟转换为（时:分）
     */
    @NonNull
    public static String string2MinuteEn2(long minute, boolean unit) {
        long h = (minute / 60);
        long m = minute - h * 60;
        if (h == 0) {
            return m + "分钟";
        }
        if (m < 10 && unit) {
            return h + "小时0" + m + "分钟";
        }
        return h + "小时" + m + "分钟";
    }

    /**
     * @param seconds:时间转换将(分钟:秒)转换为
     */
    public static int string2Millis(@NonNull String seconds) {
        String[] ms = seconds.split(":");
        int m = DoubleUtils.objToInt(ms[0]);
        int s = DoubleUtils.objToInt(ms[1]);
        return m * 60 + s;
    }


    /**
     * @param count:数字转万
     */
    @NonNull
    public static String countFormat(int count) {
        String views = "";
        if (count > 9999) {
            double f = DoubleUtils.div(count, 10000);
            views = DoubleUtils.format(f) + "万";
        } else {
            views = String.valueOf(count);
        }
        return views;
    }


    //***************************** 是否是凌晨（0-6点）  *********************************/

    /**
     * @param data:是否是凌晨（0-6点）
     */
    public static boolean isBeforeDawn(@NonNull String data) {
        return isBeforeDawn(FormatUtil.string2Calendar(data));
    }

    /**
     * @param data:是否是凌晨（0-6点）
     */
    public static boolean isBeforeDawn(@NonNull Date data) {
        return isBeforeDawn(FormatUtil.date2Calendar(data));
    }

    /**
     * 当前时间是否是凌晨（0-6点）
     */
    public static boolean isNewBeforeDawn() {
        return isBeforeDawn(nom());
    }

    /**
     * @param data:是否是凌晨（0-6点）
     */
    private static boolean isBeforeDawn(@NonNull Calendar data) {
        return data.get(Calendar.HOUR_OF_DAY) < 6;
    }

    //***************************** 判断时间是否是昨天  *********************************/

    /**
     * @param data:判断时间是否是昨天
     */
    public static boolean isYesterday(@NonNull String data) {
        return isYesterday(string2Calendar(data));
    }

    /**
     * @param data:判断时间是否是昨天
     */
    public static boolean isYesterday(@NonNull Date data) {
        return isYesterday(date2Calendar(data));
    }

    /**
     * @param data:判断时间是否是昨天
     */
    private static boolean isYesterday(@NonNull Calendar data) {
        Calendar dateFrom = nom();
        dateFrom.add(Calendar.DAY_OF_MONTH, -1);
        return twoCalendar(data, dateFrom);
    }

    //***************************** 判断时间是否是今天  *********************************/

    /**
     * @param data:判断时间是否是今天
     */
    public static boolean isToday(@NonNull String data) {
        return isToday(string2Calendar(data));
    }

    /**
     * @param data:判断时间是否是今天
     */
    public static boolean isToday(@NonNull Date data) {
        return isToday(date2Calendar(data));
    }

    /**
     * @param data:判断时间是否是今天
     */
    private static boolean isToday(@NonNull Calendar data) {
        return twoCalendar(data, null);
    }


    //***************************** 判断时间是否是明天  *********************************/

    /**
     * @param data:判断时间是否是明天
     */
    public static boolean isTomorrow(@NonNull String data) {
        return isTomorrow(string2Calendar(data));
    }

    /**
     * @param data:判断时间是否是明天
     */
    public static boolean isTomorrow(@NonNull Date data) {
        return isTomorrow(date2Calendar(data));
    }

    /**
     * @param data:判断时间是否是明天
     */
    private static boolean isTomorrow(@NonNull Calendar data) {
        Calendar dateFrom = nom();
        dateFrom.add(Calendar.DAY_OF_MONTH, 1);
        return twoCalendar(data, dateFrom);
    }

    //***************************** 判断时间是否是后天  *********************************/

    /**
     * @param data:判断时间是否是后天
     */
    public static boolean isAcquired(@NonNull String data) {
        return isAcquired(string2Calendar(data));
    }

    /**
     * @param data:判断时间是否是后天
     */
    public static boolean isAcquired(@NonNull Date data) {
        return isAcquired(date2Calendar(data));
    }

    /**
     * @param data:判断时间是否是后天
     */
    private static boolean isAcquired(@NonNull Calendar data) {
        Calendar dateFrom = nom();
        dateFrom.add(Calendar.DAY_OF_MONTH, 2);
        return twoCalendar(data, dateFrom);
    }

    //***************************** 时间是否超过当前时间  *********************************/

    /**
     * @param data:时间是否超过当前时间
     */
    public static boolean isBefore(@NonNull String data) {
        return isBefore(string2Calendar(data));
    }

    /**
     * @param data:时间是否超过当前时间
     */
    public static boolean isBefore(@NonNull Date data) {
        return isBefore(date2Calendar(data));
    }

    /**
     * @param data:时间是否超过当前时间
     */
    private static boolean isBefore(@NonNull Calendar data) {
        return data.before(nom());
    }

    //***************************** 判断时间是否相同  *********************************/

    /**
     * 两个时间是否是同一天
     *
     * @param data:
     * @param dateFrom:未null的时候判断是否是今天
     */
    public static boolean twoCalendar(@NonNull String data, String dateFrom) {
        if (TextUtils.isEmpty(dateFrom)) {
            return twoCalendar(string2Calendar(data), null);
        }
        return twoCalendar(string2Calendar(data), string2Calendar(dateFrom));
    }

    /**
     * 两个时间是否是同一天
     *
     * @param data:
     * @param dateFrom:未null的时候判断是否是今天
     */
    public static boolean twoCalendar(@NonNull Date data, Date dateFrom) {
        if (dateFrom == null) {
            return twoCalendar(date2Calendar(data), null);
        }
        return twoCalendar(date2Calendar(data), date2Calendar(dateFrom));
    }

    /**
     * 两个时间是否是同一天
     *
     * @param data:
     * @param dateFrom:未null的时候判断是否是今天
     */
    private static boolean twoCalendar(@NonNull Calendar data, Calendar dateFrom) {
        data.set(Calendar.HOUR_OF_DAY, 0);
        data.set(Calendar.MINUTE, 0);
        data.set(Calendar.SECOND, 0);
        data.set(Calendar.MILLISECOND, 0);
        //第二个时间
        if (dateFrom == null) {
            dateFrom = nom();
        }
        dateFrom.set(Calendar.HOUR_OF_DAY, 0);
        dateFrom.set(Calendar.MINUTE, 0);
        dateFrom.set(Calendar.SECOND, 0);
        dateFrom.set(Calendar.MILLISECOND, 0);
        return data.getTimeInMillis() == dateFrom.getTimeInMillis();
    }

    //***************************** 获取今天是这个月第几周  *********************************/

    /**
     * 获取今天是这个月第几周
     */
    public static int weekIndexNow() {
        return weekIndex(nom());
    }

    /**
     * 获取这个月一共几周
     */
    public static int weekIndexAll(Date time) {
        return weekIndex(lastMonthDate(time));
    }

    /**
     * @param time:获取日期是这个月第几周
     */
    private static int weekIndex(@NonNull Calendar time) {
        int day = time.get(Calendar.DATE); //今天几号：1~31
        int week = time.get(Calendar.DAY_OF_MONTH); // 今天周几：1~7
        int weekIndex = 0;
        for (int i = day; i >= 1; i--) {
            week--;
            if (week <= 0) {
                // 到了周天，要+1
                week = 7;
                weekIndex++;
            }
        }
        if (week != 7) {
            // 第一天不是周日的话，要+1
            weekIndex++;
        }
        return weekIndex;
    }

    /**
     * @param calendar:获取时间的本月最后一天
     */
    @NonNull
    public static Calendar lastMonthDate(@NonNull Date calendar) {
        Calendar data = nom();
        data.setTime(calendar);
        //下月第一天
        data.set(Calendar.DATE, 0);
        data.add(Calendar.DAY_OF_MONTH, 1);

        //这月最后一天（减一天）
        data.add(Calendar.DATE, -1);

        //增加时分秒
        data.set(Calendar.HOUR_OF_DAY, 0);
        data.set(Calendar.MINUTE, 0);
        data.set(Calendar.SECOND, 0);
        data.set(Calendar.MILLISECOND, 0);
        return data;
    }


    ///获取时间的本周第一天
    @NonNull
    public static Calendar firstWeekDate(@NonNull Date data) {
        Calendar calendar = nom();
        calendar.setTime(data);
        //今天周几，从星期一开始则减去星期天，
        int daysOfWeek = calendar.get(Calendar.DAY_OF_WEEK) - 1;
        //减去周几就是星期一
        calendar.add(Calendar.DATE, -daysOfWeek);
        return calendar;
    }


//    ///获取时间的本周第一天
//    @NonNull
//    public static String firstWeekDateStr(Calendar data) {
//        return dateAndDateFormat(firstWeekDate(data), "yyyy-MM-dd");
//    }
//
//    ///获取时间的本周第一天
//    @NonNull
//    public static Calendar lastWeekDate(Calendar data) {
//        Calendar firstDay = firstWeekDate(data);
//        firstDay.set(Calendar.DAY_OF_WEEK, 6);
//        firstDay.set(Calendar.MINUTE, 23);
//        firstDay.set(Calendar.SECOND, 59);
//        firstDay.set(Calendar.MILLISECOND, 59);
//        return firstDay;
//    }
//
//    ///获取时间的本周第一天
//    @NonNull
//    public static String lastWeekDateStr(Calendar data) {
//        return dateAndDateFormat(firstWeekDate(data), "yyyy-MM-dd");
//    }


}
